# Makefile for the GNU Pascal Run Time System
#
# Copyright (C) 1995-2006 Free Software Foundation, Inc.
#
# Authors: J.J. van der Heijden <j.j.vanderheijden@student.utwente.nl>
#          Frank Heckenbach <frank@pascal.gnu.de>
#
# This file is part of GNU Pascal.
#
# GNU Pascal is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# GNU Pascal is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GNU Pascal; see the file COPYING. If not, write to the
# Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.

# $(srcdir) is the RTS source directory
VPATH=@srcdir@
srcdir=@srcdir@

# gcc<3 doesn't set $(STAMP).
# gcc-3 does, but it should not matter to set it here again.
STAMP=echo timestamp >

GCC2GPC=sed 's,^\([^ ]*[/\][^/\]*\)gcc,\1gpc,;s/^gcc$$/gpc/' # $(CC) might be .../gcc-foo/.../xgcc

# Reasonable default values, toplevel Makefile overrides them.
# CC needs to be the GNU C compiler.
CC=@CC@
PC=`echo $(CC) | $(GCC2GPC)`
CFLAGS=-O2
PFLAGS=
AR=@AR@
AR_FLAGS=rc
RANLIB=@RANLIB@
RTSFLAGS=
GPC_DESTDIR=.
GCC_VERSION=unknown

WITH_SHARED=@with_shared@
VERSION_FILENAME=$(srcdir)/rts-version
gpc_major=2
gpc_minor=1
rts_version=`cat $(VERSION_FILENAME)`
GPCSOLIBSHORTNAME=libgpc.so
GPCSOLIBNAME=$(GPCSOLIBSHORTNAME).$(gpc_major).$(gpc_minor).$(rts_version)
GPCLIB=$(GPC_DESTDIR)/libgpc.a
GPCSOLIB=$(GPC_DESTDIR)/$(GPCSOLIBNAME)
ifdef TARGET_MACHO
       GPCSOLIBOPTIONS = -dynamiclib -dylib_install_name,$(GPCSOLIBNAME)
else
       GPCSOLIBOPTIONS = -shared -Wl,-soname=$(GPCSOLIBNAME)
endif
# PFLAGS1=--unit-path=$(VPATH) --automake -fno-strict-aliasing
PFLAGS1=--unit-path=$(VPATH) --automake
RTS_WARN=-W -Wall -Wmissing-prototypes -Wmissing-declarations
RTS_CFLAGS=-I. $(RTS_WARN) $(CFLAGS) $(RTSFLAGS)# -DDEBUG
RTS_PFLAGS=$(RTS_CFLAGS) $(PFLAGS) $(PFLAGS1) \
  -DRTS_RELEASE_STRING="'$(rts_version)'" -DGCC_VERSION="'$(GCC_VERSION)'"

PAS_SRC=rtsc.pas string1.pas error.pas heap.pas string2.pas time.pas random.pas \
 fname.pas files.pas getopt.pas sets.pas math.pas endian.pas move.pas init.pas

SRCS=rts.c $(PAS_SRC)

OBJS=rts.o rtsc.o string1.o error.o heap.o string2.o time.o random.o \
 fname.o files.o getopt.o sets.o math.o endian.o move.o init.o gpc.o $(MALLOC)

SO_OBJS=rts.lo rtsc.lo string1.lo heap.lo error.lo string2.lo time.lo random.lo \
 fname.lo files.lo getopt.lo sets.lo math.lo endian.lo move.lo init.lo gpc.lo $(MALLOC)

GENERATED_FILES=\
 $(srcdir)/acconfig.h \
 $(srcdir)/configure \
 $(srcdir)/rts-config.in \
 $(srcdir)/rtsc.pas \
 $(srcdir)/gpc.pas

all: $(GPCLIB) sharedlib.$(WITH_SHARED)

generated-files: $(GENERATED_FILES)

$(srcdir)/acconfig.h: $(srcdir)/configure.in
	m4 $(srcdir)/make-acconfig-h.m4 "$<" > "$@" || { rm -f "$@"; false; }

# The touch commands in the following rules are to prevent them from
# being run next time. Though they cause the whole RTS to be rebuilt,
# sometimes unnecessarily ...
$(srcdir)/configure: $(srcdir)/configure.in $(srcdir)/acconfig.h
	cd $(srcdir) && autoconf && touch configure && rm -rf autom4te.cache

# @@ The `rm -f "$@"' is a workaround for a bug with `mv -f' under Cygwin.
$(srcdir)/rts-config.in: $(srcdir)/configure.in $(srcdir)/acconfig.h
	rm -f "$@"; cd $(srcdir) && autoheader && touch rts-config.in && rm -rf autom4te.cache

$(srcdir)/rtsc.pas: $(srcdir)/rts.c $(srcdir)/make-rtsc-pas
	cd $(srcdir); ./make-rtsc-pas > "$@" || { rm -f "$@"; false; }

$(srcdir)/gpc.pas: $(srcdir)/rtsc.pas $(PAS_SRC) $(srcdir)/make-gpc-pas $(VERSION_FILENAME)
	version=$(rts_version); cd $(srcdir); ./make-gpc-pas $$version > "$@" || { rm -f "$@"; false; }

# @@ This might be a little risky, but since rts-config.h is generated by
#    configure, it should only contain C comments and C preprocessor directives.
rts-config.inc: rts-config.h
	echo '{ rts-config.inc.  Generated automatically from rts-config.h.  }' > rts-config.inc
	sed -e 's,/\*,{,g;s,\*/,},g;s,^[ \t]*#\(.*\),{$$\1},' rts-config.h >> rts-config.inc

# @@ `with_shared' is currently not substituted in the parent Makefile, so
#    it arrives here via the setting of $(WITH_SHARED) on the command line
DUMMY=# Don't let configure substitute `@with_shared$(DUMMY)@' below

.PHONY: all install check generated-files rts.update-release \
        sharedlib. sharedlib.no sharedlib.@with_shared$(DUMMY)@ sharedlib.yes \
        mostlyclean clean distclean extraclean maintainer-clean

install:
	@echo "There is currently no separate installation for the GNU Pascal Compiler's" >&2
	@echo "Run Time System, because it is usually built and installed together" >&2
	@echo "with GPC. You can build the RTS separately from GPC (with \`make all')" >&2
	@echo "if know what you are doing and have a current GPC version installed," >&2
	@echo "but you will have to install the resulting file(s) (libgpc.*) manually" >&2
	@echo "into the right directories, and create a symlink for the shared library" >&2
	@echo "if configured \`--with-shared'." >&2

check:
	@echo "Checks for the GPC RTS are contained in the GPC Test Suite."

rts.update-release:
	if [ -r "$(VERSION_FILENAME)" ] && [ "$(rts_version)" -ge "`date '+%Y%m%d'`" ]; then \
	  echo "RTS release version is already $(rts_version)"; \
	  exit 1; \
	fi
	date '+%Y%m%d' > $(VERSION_FILENAME)
	@echo "New RTS release version is $(rts_version)"

.SUFFIXES: .c .pas .o .lo

.c.o:
	$(CC) -c $(RTS_CFLAGS) -Wpointer-arith -Wwrite-strings $(CPPFLAGS) "$<"

.c.lo:
	$(CC) -c $(RTS_CFLAGS) -Wpointer-arith -Wwrite-strings $(CPPFLAGS) -fPIC -o "$@" "$<"

rtsc.o: rtsc.pas
	$(PC) -c -g $(RTS_PFLAGS) "$<"

rtsc.lo: rtsc.pas
	$(PC) -c -g $(RTS_PFLAGS) -fPIC -o "$@" "$<"

stamp-error-gpi: error.pas rtsc.pas string1.pas rts-version
	$(PC) -c $(RTS_PFLAGS) --interface-only "$<"
	$(STAMP) "$@"

heap.o: heap.pas stamp-error-gpi
	$(PC) -c $(RTS_PFLAGS) --no-automake "$<"

heap.lo: heap.pas stamp-error-gpi
	$(PC) -c $(RTS_PFLAGS) --no-automake -fPIC -o "$@" "$<"

error.o: error.pas heap.o
	$(PC) -c $(RTS_PFLAGS) --no-automake --implementation-only "$<"

error.lo: error.pas heap.lo
	$(PC) -c $(RTS_PFLAGS) --no-automake --implementation-only "$<" -fPIC -o "$@"

endian.o: endian.pas error.o
	$(PC) -c $(RTS_PFLAGS) --no-automake -fno-strict-aliasing "$<"

endian.lo: endian.pas error.lo
	$(PC) -c $(RTS_PFLAGS) --no-automake -fno-strict-aliasing -fPIC -o "$@" "$<"

.pas.o:
	$(PC) -c $(RTS_PFLAGS) "$<"

.pas.lo:
	$(PC) -c $(RTS_PFLAGS) -fPIC -o "$@" "$<"

init.o init.lo: $(VERSION_FILENAME)

# After a change in the compiler that influences the GPI format
# or a change to the RTS's interface modify rtsc.pas (don't just
# touch it if you're going to distribute the patch), so the
# following rule will force the complete RTS to be recompiled.
$(OBJS) $(SO_OBJS): rtsc.pas constants.def rts-config.inc

$(GPCLIB): $(OBJS)
	-rm -f $(GPCLIB)
	$(AR) $(AR_FLAGS) $(GPCLIB) $(OBJS)
	-$(RANLIB) $(GPCLIB) 2> /dev/null

# That's a way to do an `if' that even a stupid make understands ...
sharedlib. sharedlib.no sharedlib.@with_shared$(DUMMY)@:
sharedlib.yes: $(GPCSOLIB)
$(GPCSOLIB): $(SO_OBJS)
	-rm -f $(GPCSOLIB)
	$(CC) $(GPCSOLIBOPTIONS) -fPIC -o $(GPCSOLIB) $(SO_OBJS)

mostlyclean:
	-rm -f $(OBJS) $(SO_OBJS) *.gpi *.gpd core stamp-error-gpi

clean: mostlyclean
	-rm -f $(GPCLIB) $(GPCSOLIB)

distclean: clean
	-rm -f Makefile rts-config.h rts-config.inc config.cache config.log config.status

extraclean: distclean
	-rm -f *~* *.i *.s

maintainer-clean: extraclean
	-rm -f $(GENERATED_FILES)
